

;http://mason.gmu.edu/~gcaldero/docs/CS687_P5_planner.lisp
(defstruct operator
   "Defines a strips operator"
  name uniq preconditions effects)



(defparameter *operators*
   (list
    ;; move from table operators
    (make-operator :name 'a-table-to-b
          :preconditions '((t a-on-table) (t b-clear) (t a-clear))
          :effects '((nil a-on-table) (nil b-clear) (t a-on-b)))))
    
    
(defun copy-operator (operator)
  "Copies the operator and assigns it a new unique gensym symbol to make
it unique as far as EQUALP is concerned.  Returns the copy."
  ;; I suggest you use this code to guarantee that the operator is properly
  ;; copied out of the templates.
  (let ((op (copy-structure operator)))
    (setf (operator-uniq op) (gensym))
    op))
    

;========================================
;;; LINKS
(defstruct (link
        (:print-function print-link))
  "FROM and TO are the gensyms corresponding to operators in the plan.
  PRECOND is the predicate that FROM's effect makes true in TO's precondition."
  from precond to)
 
(defun print-link (p stream depth)
  "Helper function to print link in a pretty way"
  (declare (ignorable depth))
  (format stream "#< (~a)~a -> (~a)~a : ~a >"
      (when (link-from p) (operator-uniq (link-from p)))
      (when (link-from p) (operator-name (link-from p)))
      (when (link-to p) (operator-uniq (link-to p)))
      (when (link-to p) (operator-name (link-to p)))
      (link-precond p)))

;========================================
;;; ORDERING
(defun print-ordering (p stream depth)
  "Helper function to print link in a pretty way"
  (declare (ignorable depth))
  (format stream "#[ (~a)~a -> (~a)~a ]"
      (operator-uniq (first p))
      (operator-name (first p))
      (operator-uniq (rest p))
      (operator-name (rest p))))

;========================================
;;; PLANS
(defstruct (plan (:print-function print-plan))
  "A collection of lists of operators, orderings, and links,
plus a pointer to the start operator and to the goal operator."
  operators orderings links start goal)
 
(defun print-plan (p stream depth)
  "Helper function print plan in a pretty way"
  (declare (ignorable depth))
  (format stream "#< PLAN operators: ~{~%~a~} ~%links: ~{~%~a~} ~%orderings: ~{~%~a~}~%>"
      (plan-operators p) (plan-links p)
      (mapcar #'(lambda (ordering)
              (print-ordering ordering nil 0))
          (plan-orderings p))))
 
;; Expect a possible warning here about redefinition
(defun copy-plan (plan)
  ;; I suggest you use this code to guarantee that the plan is copied
  ;; before you do any destructive coding on it.
  "Deep-copies the plan, and copies the operators, orderings, and links."
  (let ((p (copy-structure plan)))
    (setf (plan-operators p) (copy-tree (plan-operators p)))
    (setf (plan-orderings p) (copy-tree (plan-orderings p)))
    (setf (plan-links p) (copy-tree (plan-links p)))
    p))
 